package com.travel.common.util;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.travel.common.CommonRes.BusinessException;
import com.travel.common.CommonRes.CommonErrorCode;
import com.travel.pojo.User;
import io.jsonwebtoken.*;
import redis.clients.jedis.Jedis;

import java.util.Date;

public class JwtUtil {

    private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo4x3c+bm28IzoBEQmObxbMA6YPekQv57/IZJKD6EeTLc9zux7PRsth5HBIWG0micAfYixeyQrXyG3UYfQrori82Jp+oWN8/rp8cZKtJThj/p/pJ8gdIjqLPBng6LgGH2AS4GCPIunPcjzSCuf09ztr0A6nPJsJsudkz6Sh39n5brEbtAyvbolofCGnVjqWtWmEZAUcB+Apro6YctTlUSKla0DWanjgpjtDvK518QxKPw0WNuNX0WF8ciT8V8l11tCs4Lq+HHk59LlcUl627lShqmy7cLN1yiNxkmGRZKsYF2Dh3sSKuyA510f1J54zlkCT9BhD2LkSzJr3X3U9/SbwIDAQAB";
    private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCjjHdz5ubbwjOgERCY5vFswDpg96RC/nv8hkkoPoR5Mtz3O7Hs9Gy2HkcEhYbSaJwB9iLF7JCtfIbdRh9CuiuLzYmn6hY3z+unxxkq0lOGP+n+knyB0iOos8GeDouAYfYBLgYI8i6c9yPNIK5/T3O2vQDqc8mwmy52TPpKHf2flusRu0DK9uiWh8IadWOpa1aYRkBRwH4Cmujphy1OVRIqVrQNZqeOCmO0O8rnXxDEo/DRY241fRYXxyJPxXyXXW0Kzgur4ceTn0uVxSXrbuVKGqbLtws3XKI3GSYZFkqxgXYOHexIq7IDnXR/UnnjOWQJP0GEPYuRLMmvdfdT39JvAgMBAAECggEASyj0hHkqwvd+jiMJg5sufBHjQkjMXlVhWW3FFQ+WBbTQQ3ZVkFXL1+4WKQfMK8oTV/trg5Xx7yh5OhtNpna0KG1uw5IaX8/XtqUS9dDuvZWFzY44VdjitlbVtfNtPLTIP0aNU3Mo5M3W0CAi0TMMNICreRN5LwZB1fAOXh1mPv55OVfFXepRhO3uLxLLUPmmbV4lrY5vloTe903jShrT/DRIowQCO6raMIShNUbJwNF8jOakZBFjVdLljHnCfRCbkhbblwdNfOzuC+KBJwD62Sh2AR3pyrsxQTJfmy8oV11Eh3XBakWyWm/MXLWxazPaEVMnUS+Y+ztZpCL4tmCtoQKBgQDi6lqR1JW68O6/WuCdO5YTGE0X2rNDDae4hWyze6q8KrQ6qQJSqa9wOvevmB0tCv0V04kDMkU8ey+EV2C/rtdRZ1KzQxHMtxKeU0rLtmYDHy52Jiblc/ry8m7SZaMHgQFy4ds9zhHOtXjLyFy1+9BhVrBbvFw5mak452C3A/+jlwKBgQC4guVpb5dCbVDntcxGscpAvL4gOQBeZK+NG0CEMV7Jvc8ke+5gWkYPPV5oXtiikXzaswblQInPqBCtkH8hYxmgeBg9PqU0O+F/XsuAJ6ecoyatLIIZE2ze4aCuZg+HVlPzJyQgH1HavHh6b9lxRv1BR9/CmvV7A6p82F0VzRFC6QKBgDD1V203bMbUzO5EcUn7XTnpeFi5OwwwmgtZ3kYrXH8Ux6YQaQvkyJFyZ5ZfP4xEXq6i4WDrK70M5weqwpkY5CQQIuvCgMimh0HZvr2NMR1jUOb0/FdtWquoWvjSLQalcuaSjHcdSwJKbTGqnTY2ipM13P8t+MgEu1onsdpK5pEpAoGBAKEzMw0XwlX1va6CpXLKF8LRY2YxhsHxQ3KLcaVMoNyuqQ/d+phRpk3gNuAGpUv6wdMsgATAiuZSliedS4S22QfahIrVdW4aNtuZzT8s5gIyhDLd5NfVodNj2ocjgcOix3tzIduyoUfyS2vk1ltiQxbKnZKe4YNU45lpSoImhEMpAoGBAK948oHgbVRBFArO0XxNQ0acYHaOaAdxyZywb0oWvHLXQrAu8Wa45Gj3C+iR/p6oGOGLAiXPArqo1mq5awfLI4T62PAziKd/jAqlYnLdoNpiQM7HZcHbQoeVsusATNJzI321ng+Rd8TYWbOMasm2S3qLc+lxK+ad/Z6nDj1IyTGk";//加密key,
    private static final long EXPIRATION_TIME = 24 * 60 * 60; // 24 小时
    private static final long RENEWAL_WINDOW = 1 * 60 * 60; // 1 小时
    private static Jedis jedis = new Jedis("121.40.188.63");

    // 生成 token
    public static String generateToken(User userInfo) {
        String token = Jwts.builder()
                .setSubject(String.valueOf(userInfo.getUserid()))
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME * 1000))
                .signWith(SignatureAlgorithm.HS256, PRIVATE_KEY)
                .compact();

        jedis.set(token, JsonUtil.objectTojson(userInfo));
        jedis.expire(token, (int)EXPIRATION_TIME);

        return token;
    }

    // 从 token 中解析出 userId
    public static Integer getUserIdFromToken(String token) throws ExpiredJwtException, MalformedJwtException, SignatureException {

        String userInfoJson = jedis.get(token);

        if (userInfoJson == null) {
            throw new BusinessException(CommonErrorCode.E_110003);
        }

        // 使用 JSON 解析库将 JSON 字符串解析为一个对象
        ObjectMapper objectMapper = new ObjectMapper();
        User userInfo = null;
        try {
            userInfo = objectMapper.readValue(userInfoJson, User.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        // 返回用户 ID
        return userInfo.getUserid();
    }

    // 从 Redis 中获取用户信息
    public static Integer getUserInfoFromRedis(String token) {
        String s = jedis.get(token);
        User user = JSONObject.parseObject(s, User.class);
        return user.getUserid();
    }

    // 判断 token 是否过期
    public static boolean shouldTokenBeRenewed(String token) {
        String userInfo = jedis.get(token);
        if (userInfo == null) {
            // 用户首次访问，不需要续期
            return false;
        }

        long lastAccessTimeLong = Long.parseLong(userInfo);
        return System.currentTimeMillis() / 1000 - lastAccessTimeLong > EXPIRATION_TIME - RENEWAL_WINDOW;
    }

    // 更新 token 的最后访问时间
    public static void updateLastAccessTime(String token, User userInfo) {
        jedis.set(token, JsonUtil.objectTojson(userInfo));
        jedis.expire(token, (int)EXPIRATION_TIME);
    }

}
